/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { SetupContext } from 'vue';
import { TooltipPlacement, TooltipProps } from '../tooltip.props';
import { TooltipPosition } from './types';

export function useAdjustPosition(props: TooltipProps, context: SetupContext) {
    const rectifyGutter = 6;

    /**
     * 判断是否超出边界
     */
    function isOverstepBoundary(referenceBoundingRect: DOMRect, direct: string, value: number) {
        let overBound = false;
        let fixedValue = value;

        if ((direct === 'left' || direct === 'top') && value <= referenceBoundingRect[direct]) {
            overBound = true;
            fixedValue = referenceBoundingRect[direct] + rectifyGutter;
        }
        if ((direct === 'right' || direct === 'bottom') && value >= referenceBoundingRect[direct]) {
            overBound = true;
            fixedValue = referenceBoundingRect[direct] - rectifyGutter;
        }
        return { overBound, fixedValue };
    }

    function adjustPosition(
        placementAndAlignment: TooltipPlacement,
        originalPosition: TooltipPosition,
        relativeElementRect: DOMRect,
        hostRect: DOMRect,
        tooltipRect: DOMRect,
        tooltipContentRect: DOMRect,
        arrowRect: DOMRect
    ): TooltipPosition {
        let fixedLeft = originalPosition.tooltip.left;
        let fixedTop = originalPosition.tooltip.top;
        let fixedArrowLeft = originalPosition.arrow.left;
        let fixedArrowTop = originalPosition.arrow.top;
        const placementAndAlignmentArray = placementAndAlignment.split('-');
        const placement = placementAndAlignmentArray[0];
        if (['top', 'bottom'].includes(placement)) {
            const overLeftBound = isOverstepBoundary(relativeElementRect, 'left', originalPosition.tooltip.left);
            const overRightBound = isOverstepBoundary(relativeElementRect, 'right', originalPosition.tooltip.left + tooltipRect.width);
            fixedLeft = overLeftBound.overBound
                ? overLeftBound.fixedValue
                : overRightBound.overBound
                ? overRightBound.fixedValue - tooltipRect.width
                : originalPosition.tooltip.left;
            fixedArrowLeft = overLeftBound.overBound
                ? tooltipRect.width - (fixedLeft + tooltipRect.width - hostRect.right) - arrowRect.width
                : overRightBound.overBound
                ? hostRect.left - fixedLeft
                : originalPosition.arrow.left;
        }
        const overTopBound = isOverstepBoundary(relativeElementRect, 'top', originalPosition.tooltip.top);
        const overBottomBound = isOverstepBoundary(relativeElementRect, 'bottom', originalPosition.tooltip.top + tooltipRect.height);
        fixedTop = overTopBound.overBound
            ? overTopBound.fixedValue
            : overBottomBound.overBound
            ? overBottomBound.fixedValue - tooltipRect.height
            : originalPosition.tooltip.top;
        fixedArrowTop = overTopBound.overBound
            ? originalPosition.arrow.top
            : overBottomBound.overBound
            ? tooltipRect.height - (fixedTop + tooltipRect.height - hostRect.top)
            : originalPosition.arrow.top;
        const tooltip = { left: fixedLeft, top: fixedTop };
        const arrow = { left: fixedArrowLeft, top: fixedArrowTop };
        return { arrow, tooltip };
    }

    return { adjustPosition };
}
